Projeto base de aprendizado de máquina

Projeto de Aprendizado de máquina

Para a realização do projeto de aprendizado de máquina, foi escolhido o conjunto de dados IRIS nativo da biblioteca scikit-learn. Foi criado um documento Rmarkdown, porém codificado em python com o auxílio da biblioteca reticulate.

Coleta de dados

Primeiramente, foi importado as classes necessárias para o projeto. A estrutura de importação da linguagem python se estrutura em módulos. Um módulo é um arquivo contendo uma função em específico que podemos utiliza-la no nosso código:

  • from nome_do_arquivo import nome_da_função|classe
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import pandas as pd
import plotly.express as px

dados = load_iris().data
colunas = load_iris().feature_names

df = pd.DataFrame(data = dados, columns = colunas)

df['target'] = load_iris().target

Divisão dos dados

Antes de realizar qualquer coisa, deve-se dividir os dados em treino e teste. Isso é feito com o objetivo de evitar o viés de espionagem, onde acabamos por ajustar o modelo aos dados de teste. Portanto, deve-se realizar todo o processo de análise, transoformação e comparação de modelos com os dados de treino, para que no final se utlize os dados de teste.

Foi usado o parâmetro stratify para dividir os dados respeitando o desbalanceamento dos rótulos.


df_treino,df_teste = train_test_split(df, stratify = df['target'])

Análise Exploratória

Foi feito uma análise descritiva bem simples com algumas colunas.

print(df_treino.describe())
##        sepal length (cm)  sepal width (cm)  ...  petal width (cm)      target
## count         112.000000        112.000000  ...        112.000000  112.000000
## mean            5.854464          3.072321  ...          1.200893    0.991071
## std             0.846497          0.452064  ...          0.767175    0.821946
## min             4.300000          2.000000  ...          0.100000    0.000000
## 25%             5.100000          2.800000  ...          0.300000    0.000000
## 50%             5.800000          3.000000  ...          1.300000    1.000000
## 75%             6.500000          3.400000  ...          1.800000    2.000000
## max             7.900000          4.400000  ...          2.500000    2.000000
## 
## [8 rows x 5 columns]
df_treino.head(5)
##      sepal length (cm)  sepal width (cm)  ...  petal width (cm)  target
## 20                 5.4               3.4  ...               0.2       0
## 122                7.7               2.8  ...               2.0       2
## 98                 5.1               2.5  ...               1.1       1
## 84                 5.4               3.0  ...               1.5       1
## 101                5.8               2.7  ...               1.9       2
## 
## [5 rows x 5 columns]
px.histogram(df_treino['sepal length (cm)'])
px.histogram(df_treino['sepal width (cm)'])
px.histogram(df_treino['petal length (cm)'])
px.histogram(df_treino['petal width (cm)'])
px.bar(df_treino['target'].value_counts().sort_values(ascending = False))

Imputação e transformação

Para a realização da imputação dos dados, deve-se primeiro fazer para os dados de treino e depois para os de teste. Como não sabemos quais dados estão nulos no teste, realizaremos do mesmo jeito, já que o algoritmo de imputação identifica quais colunas possuem ou não valores nulos.

x_treino = df_treino.drop(['target'], axis = 1)

y_treino = df_treino['target']

A classe Pipeline tem como função juntar os componentes de imputação e transformação dos dados de forma a automatizar processos.

pipe = Pipeline([
  ('imputer', SimpleImputer(strategy = 'mean') ),
  ('scale', StandardScaler())
])
x_treino_preparado = pipe.fit_transform(x_treino)

Treinamento e Seleção do Modelo

Foi utilizado as principais métricas de classificação:

  • Precision;
  • Recall
  • F1-score
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier

pred = cross_val_predict(RandomForestClassifier(),x_treino_preparado,y_treino, cv = 4)

print(classification_report(y_treino,pred))
##               precision    recall  f1-score   support
## 
##            0       1.00      1.00      1.00        38
##            1       0.92      0.95      0.93        37
##            2       0.94      0.92      0.93        37
## 
##     accuracy                           0.96       112
##    macro avg       0.96      0.95      0.95       112
## weighted avg       0.96      0.96      0.96       112
from sklearn.neighbors import KNeighborsClassifier

pred = cross_val_predict(KNeighborsClassifier(),x_treino_preparado,y_treino, cv = 4)

print(classification_report(y_treino,pred))
##               precision    recall  f1-score   support
## 
##            0       1.00      1.00      1.00        38
##            1       0.95      0.95      0.95        37
##            2       0.95      0.95      0.95        37
## 
##     accuracy                           0.96       112
##    macro avg       0.96      0.96      0.96       112
## weighted avg       0.96      0.96      0.96       112
from sklearn.svm import SVC

pred = cross_val_predict(SVC(),x_treino_preparado,y_treino, cv = 4)

print(classification_report(y_treino,pred))
##               precision    recall  f1-score   support
## 
##            0       1.00      0.97      0.99        38
##            1       0.95      0.95      0.95        37
##            2       0.95      0.97      0.96        37
## 
##     accuracy                           0.96       112
##    macro avg       0.96      0.96      0.96       112
## weighted avg       0.96      0.96      0.96       112

Foi observado que o algoritmo Random Forest se mostrou superior.

Aprimoramento do Modelo

Para o aprimoramento do modelo, foi utilizado a técnica de pesquisa em grade com dois hiperparâmetros do Random Forest.


from sklearn.model_selection import GridSearchCV

random_grid = {'n_estimators': [200,300],
               'max_features': [3,4]
               }
               
               
grade = GridSearchCV(RandomForestClassifier(), param_grid = random_grid, cv =4)

grade.fit(x_treino_preparado,y_treino)
## GridSearchCV(cv=4, estimator=RandomForestClassifier(),
##              param_grid={'max_features': [3, 4], 'n_estimators': [200, 300]})
modelo_final = grade.best_estimator_

Teste final

Para o teste final, foi usado a classe Pipeline e o modelo final encontrado na pesquisa em grade.

x_teste = df_teste.drop(['target'], axis = 1)
y_teste = df_teste['target']

x_teste_preparado = pipe.transform(x_teste)

modelo_final.fit(x_treino_preparado, y_treino)
## RandomForestClassifier(max_features=3, n_estimators=200)
pred_final = modelo_final.predict(x_teste_preparado)

print(classification_report(y_teste,pred_final))
##               precision    recall  f1-score   support
## 
##            0       1.00      1.00      1.00        12
##            1       0.87      1.00      0.93        13
##            2       1.00      0.85      0.92        13
## 
##     accuracy                           0.95        38
##    macro avg       0.96      0.95      0.95        38
## weighted avg       0.95      0.95      0.95        38